package cn.demoncat.util.mybatis.entity;

import cn.demoncat.util.lang.entity.PageParam;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import java.util.List;
import java.util.function.Supplier;

/**
 * 描述：分页（继承通用Pager，依赖PageHelper）
 *
 * @author 延晓磊
 *
 * @since 2015年7月10日
 */
public class Pager<T> extends cn.demoncat.util.lang.entity.Pager<T> {
 
	public Pager() {
		super();
	}

	public Pager(cn.demoncat.util.lang.entity.Pager pager) {
		super(pager);
	}

	public Pager(Integer pageNum, Integer pageSize) {
		super(pageNum, pageSize);
	}

	public Pager(Integer pageNum, Integer pageSize, Long totalCount) {
		super(pageNum, pageSize, totalCount);
	}

	/**
	 * 开始分页 - findPage
	 *
	 * 用法：列表查询前调用，PageHelper将自动Count查询，然后根据数据总数和分页参数作Limit查询，最后返回分页数据
	 *
	 * 注意：列表查询，必须是下一个查询
	 * 
	 * @param pageNum	页码：null/0/负数 == 首页，大于页数 == 尾页
	 * @param pageSize  页长：null/0/负数 == 10，最大10000
	 * 
	 * @author 延晓磊
	 *
	 * @since 2018年11月9日
	 */
	public static void startPage(Integer pageNum, Integer pageSize) {
		//初始化分页参数
		PageParam pp = Pager.initPageParams(pageNum, pageSize);
		//分页：创建Page存放到ThreadLocal中，在查询前进行count
		PageHelper.startPage(pp.getPageNum(),pp.getPageSize(),true,true,false);
	}
	
	/**
	 * 开始分页 - findList
	 * 
	 * 用法：列表查询前调用，PageHelper将根据分页参数作Limit查询，不会进行count查询及尾页优化
	 *
	 * 注意：列表查询，必须是下一个查询
	 *
	 * @param pageNum	页码：null/0/负数 == 首页
	 * @param pageSize  页长：null/0/负数 == 10，最大10000
	 * 
	 * @author 延晓磊
	 *
	 * @since 2018年11月9日
	 */
	public static void startList(Integer pageNum, Integer pageSize) {
		//初始化分页参数
		PageParam pp = Pager.initPageParams(pageNum, pageSize);
		//分页：创建Page存放到ThreadLocal中，在查询前进行count
		PageHelper.startPage(pp.getPageNum(),pp.getPageSize(),false,false,false);
	}
	
    /**
     * 功能描述：将PageHelper分页查询的List结果转换为Pager
     *
     * @param pageList
     * @return
     * 
     * @author 延晓磊
     *
     * @since 2017年7月16日
     */
    public static <T> Pager<T> getPager(List<T> pageList){
    	//转换List为PageHelper的Page
    	Page<T> page = (Page<T>)pageList;
    	//分页属性：页号，页长，起始索引，末索引，页数，总数，结果List
    	Pager<T> pager = new Pager<>();
    	pager.setPageNum(page.getPageNum());
    	pager.setPageSize(page.getPageSize());
    	pager.setPageCount(page.getPages());
    	pager.setTotalCount(page.getTotal());
    	pager.setList(page.getResult());
    	return pager;
    }
    
    /**
     * SSM分页查询
     * 
     * 例：Pager.findPage(pageNum, pageSize, () -> mailInMapper.findMail(condition));
	 *
	 * 注意：列表查询，必须是下一个查询。分页插件会将下一个查询拦截处理，返回Pager extends List
     * 
     * @param pageNum	页码：null/0/负数 == 首页
     * @param pageSize	页长：null/0/负数 == 10，最大10000
     * @param supply	Mapper条件查询列表
     * @return
     * 
     * @author 延晓磊
     *
     * @since 2020年4月20日
     */
    public static <T>Pager<T> findPage(Integer pageNum, Integer pageSize, Supplier<List<T>> supply){
    	// 开始分页
    	Pager.startPage(pageNum, pageSize);
    	// 查询
    	return getPager(supply.get());
    }
     
    /**
     * SSM分页查询
     * 
     * 例：Pager.findList(pageNum, pageSize, () -> mailInMapper.findMail(condition));
     * 
     * @param pageNum	页码：null/0/负数 == 首页
     * @param pageSize	页长：null/0/负数 == 10，最大10000
     * @param supply	Mapper条件查询列表
     * @return
     * 
     * @author 延晓磊
     *
     * @since 2020年4月20日
     */
    public static <T>List<T> findList(Integer pageNum, Integer pageSize, Supplier<List<T>> supply){
    	// 开始分页
    	Pager.startPage(pageNum, pageSize);
    	// 查询
    	return supply.get();
    }
}